import {Callout, Tabs} from 'nextra/components';
import { Widget } from '@/components/demo/widget.tsx';
import LinkBadge from '@/components/ui/link-badge/link-badge.tsx';
import LinkBadgeGroup from '@/components/ui/link-badge/link-badge-group.tsx';

# Checkbox

A control that allows the user to toggle between checked and not checked.

<LinkBadgeGroup>
    <LinkBadge label="API Reference" href="https://pub.dev/documentation/forui/latest/forui.widgets.checkbox/"/>
</LinkBadgeGroup>

<div className="pb-5">
    <Callout type="info">
        For touch devices, a [switch](/docs/form/switch) is generally recommended over this.
    </Callout>

    <Callout type="info">
        We recommend using a [select group](/docs/form/select-group#checkbox-form) to create a group of checkboxes.
    </Callout>

</div>

<Tabs items={['Preview', 'Code']}>
    <Tabs.Tab>
        <Widget name='checkbox' query={{enabled: 'true'}}/>
    </Tabs.Tab>
    <Tabs.Tab>
        ```dart copy
        class Page extends StatefulWidget {
          const Page({super.key});

          @override
          State<Page> createState() => PageState();
        }

        class PageState extends State<Page> {
          bool state = false;

          @override
          Widget build(BuildContext context) => FCheckbox(
            label: const Text('Accept terms and conditions'),
            description: const Text('You agree to our terms and conditions.'),
            semanticsLabel: 'Accept terms and conditions',
            value: state,
            onChange: (value) => setState(() => state = value),
          );
        }
        ```
    </Tabs.Tab>

</Tabs>

## CLI

To generate and customize this style:

```shell copy
dart run forui style create checkbox
```

## Usage

### `FCheckbox(...)`

```dart copy
FCheckbox(
  style: FCheckboxStyle(...),
  label: const Text('Accept terms and conditions'),
  description: const Text('You agree to our terms and conditions.'),
  error: const Text('Please accept the terms and conditions.'),
  semanticsLabel: 'Accept terms and conditions',
  value: true,
  onChange: (value) {},
  enabled: true,
  autofocus: true,
);
```

## Examples

### Disabled

<Tabs items={['Preview', 'Code']}>
  <Tabs.Tab>
    <Widget name='checkbox' query={{initialValue: 'true', enabled: 'false'}}/>
  </Tabs.Tab>
  <Tabs.Tab>
    ```dart {18} copy
    class Page extends StatefulWidget {
      const Page({super.key});

      @override
      State<Page> createState() => PageState();
    }

    class PageState extends State<Page> {
      bool state =  true;

      @override
      Widget build(BuildContext context) => FCheckbox(
        label: const Text('Accept terms and conditions'),
        description: const Text('You agree to our terms and conditions.'),
        semanticsLabel: 'Accept terms and conditions',
        value: state,
        onChange: (value) => setState(() => state = value),
        enabled: false,
      );
    }
    ```

  </Tabs.Tab>
</Tabs>

### Error

<Tabs items={['Preview', 'Code']}>
  <Tabs.Tab>
    <Widget name='checkbox' query={{ error: 'Please accept the terms and conditions.' }}/>
  </Tabs.Tab>
  <Tabs.Tab>
    ```dart {15} copy
    class Page extends StatefulWidget {
      const Page({super.key});

      @override
      State<Page> createState() => PageState();
    }

    class PageState extends State<Page> {
      bool state = false;

      @override
      Widget build(BuildContext context) => FCheckbox(
        label: const Text('Accept terms and conditions'),
        description: const Text('You agree to our terms and conditions.'),
        error: const Text('Please accept the terms and conditions.'),
        semanticsLabel: 'Accept terms and conditions',
        value: state,
        onChange: (value) => setState(() => state = value),
      );
    }
    ```

  </Tabs.Tab>
</Tabs>

### Without Label

<Tabs items={['Preview', 'Code']}>
    <Tabs.Tab>
        <Widget name='checkbox' variant='raw' query={{ }}/>
    </Tabs.Tab>
    <Tabs.Tab>
        ```dart {12-17} copy
        class Page extends StatefulWidget {
          const Page({super.key});

          @override
          State<Page> createState() => PageState();
        }

        class PageState extends State<Page> {
          bool state = false;

          @override
          Widget build(BuildContext context) => FCheckbox(
            value: state,
            onChange: (value) {
              setState(() => state = value);
            },
          );
        }
        ```
    </Tabs.Tab>

</Tabs>

### Form

<Tabs items={['Preview', 'Code']}>
  <Tabs.Tab>
    <Widget name='checkbox' variant='form' query={{}} height={550}/>
  </Tabs.Tab>
  <Tabs.Tab>
    ```dart {27-40} copy
    class RegisterForm extends StatefulWidget {
      const RegisterForm({super.key});

      @override
      State<RegisterForm> createState() => _RegisterFormState();
    }

    class _RegisterFormState extends State<RegisterForm> {
      final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

      @override
      Widget build(BuildContext context) => Form(
            key: _formKey,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                FTextFormField.email(
                  hint: 'janedoe@foruslabs.com',
                  validator: (value) => (value?.contains('@') ?? false) ? null : 'Please enter a valid email.',
                ),
                const SizedBox(height: 12),
                FTextFormField.password(
                  validator: (value) => 8 <= (value?.length ?? 0) ? null : 'Password must be at least 8 characters long.',
                ),
                const SizedBox(height: 15),
                FormField(
                  initialValue: false,
                  onSaved: (value) {
                    // Save values somewhere.
                  },
                  validator: (value) => (value ?? false) ? null : 'Please accept the terms and conditions.',
                  builder: (state) => FCheckbox(
                    label: const Text('Accept terms and conditions'),
                    description: const Text('You agree to our terms and conditions.'),
                    error: state.errorText != null ? Text(state.errorText!) : null,
                    value: state.value ?? false,
                    onChange: (value) => state.didChange(value),
                  ),
                ),
                const SizedBox(height: 20),
                FButton(
                  onPress: () {
                    if (!_formKey.currentState!.validate()) {
                      // Handle errors here.
                      return;
                    }

                    _formKey.currentState!.save();
                    // Do something.
                  },
                  child: const Text('Register'),
                ),
              ],
            ),
          );
    }
    ```

  </Tabs.Tab>
</Tabs>
